<?php
namespace app\common\service\product;

use app\common\enums\RefundStatusEnum;
use app\common\enums\RefundTypeEnum;
use app\common\enums\OrderStatusEnum;
use app\common\enums\PayStatusEnum;
use app\common\model\product\Product;
use app\common\model\product\ProductOrder;
use app\common\model\product\ProductOrderProduct;
use app\common\model\product\ProductSku;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use app\common\library\wechat\WxPay;

/**
 * Class OrderService
 * @package app\common\service\product
 * @author luoxianhui
 */
class OrderService
{
    public $noticeService;

    public function __construct()
    {
        $this->noticeService = new NoticeService();
    }

    /**
     * 付款成功处理
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function paySuccess($orderId,$payment_type = 1){
        $order = ProductOrder::where('id', $orderId)->find();
        if ($order->pay_status == PayStatusEnum::PAY_STATUS_SUCCESS) {
            return true;
        }

        $orderStatus = ($order->delivery_type == 1) ? OrderStatusEnum::SHIPMENTS : OrderStatusEnum::PAY;
        $order->order_status = $orderStatus;
        $order->pay_status = PayStatusEnum::PAY_STATUS_SUCCESS;
        $order->pay_time = time();
        $order->payment_type = $payment_type;
        $order->save();

        $orderProductList = ProductOrderProduct::where('order_id', $orderId)->select();
        foreach ($orderProductList as $orderProduct) {
            $productModel = Product::where('id', $orderProduct->product_id)->find();
            $productModel->sale += $orderProduct->num;
            $productModel->save();

            $orderProduct->order_status = $orderStatus;
            $orderProduct->save();

            $skuModel = ProductSku::where('id', $orderProduct->sku_id)->find();
            $skuModel->stock -= $orderProduct->num;
            if ($skuModel->stock < 0) {
                $skuModel->stock = 0;
            }
            $skuModel->save();
        }

        //消息推送
        $this->noticeService->orderPaySuccessNotice($orderId);
    }


    /**
     * 取消订单
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function cancelOrder($orderId){
        $order = ProductOrder::where('id', $orderId)->find();
        if (!self::isCancel($order->order_status)) {
            return false;
        }
        $order->order_status = OrderStatusEnum::REPEAL;
        $order->save();
        ProductOrderProduct::where('order_id', $orderId)->update(['order_status' => OrderStatusEnum::REPEAL]);
        return true;
    }


    /**
     * 确认收货
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function confirmReceipt($orderId){
        $order = ProductOrder::where('id', $orderId)->find();
        if (!self::isReceipt($order->order_status)) {
            return false;
        }
        $order->order_status = OrderStatusEnum::ACCOMPLISH;
        $order->save();
        ProductOrderProduct::where('order_id', $orderId)->update(['order_status' => OrderStatusEnum::ACCOMPLISH]);
        
         //给商家发送用户收货通知
        $this->noticeService->confirmReceiptNotice($orderId);
        return true;
    }
    
    
    /**
     * 自动收货
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function autoReceiptHandle(){
        $times = time() - 3600*24*15;
        $orderList = ProductOrder::where('order_status', OrderStatusEnum::SHIPMENTS)->where('pay_time','<=', $times)->field('id')->select();
        if (count($orderList) > 0) {
            foreach ($orderList as $v) {
                $this->confirmReceipt($v['id']);
            }
        }
        return true;
    }


    /**
     * 申请售后
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function applyAfterSales($orderId){
        $order = ProductOrder::where('id', $orderId)->find();
        if (!self::isSales($order->order_status, $order->admin_id,$orderId)) {
            return false;
        }
        $order->order_status = OrderStatusEnum::RETUREN_ING;
        $order->save();
        ProductOrderProduct::where('order_id', $orderId)->update(['order_status' => OrderStatusEnum::RETUREN_ING]);
        //给商家发送售后申请通知
        $this->noticeService->afterSalesNotice($orderId);
        return true;
    }


    /**
     * 取消申请售后
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function cancelAfterSales($orderId){
        $order = ProductOrder::where('id', $orderId)->find();
        if (!self::isCancelSales($order->order_status)) {
            return false;
        }
        $order->order_status = OrderStatusEnum::ACCOMPLISH;
        $order->save();
        ProductOrderProduct::where('order_id', $orderId)->update([
            'order_status' => OrderStatusEnum::ACCOMPLISH,
            'refund_status' => RefundStatusEnum::CANCEL,
        ]);
        //给商家发送 取消售后申请通知
        $this->noticeService->cancelAfterSalesNotice($orderId);
        return true;
    }

    /**
     * 同城配送
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function localDelivery($orderId){
        $order = ProductOrder::where('id', $orderId)->find();
        if (!self::isDelivery($order->order_status)) {
            return false;
        }
        $order->order_status = OrderStatusEnum::SHIPMENTS;
        $order->save();

        ProductOrderProduct::where('order_id', $orderId)->update([
            'order_status' => OrderStatusEnum::SHIPMENTS,
        ]);

        //给商家发送 取消售后申请通知
        $this->noticeService->localDeliveryNotice($orderId);
        return true;
    }

    /**
     * 快递配送
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function expressDelivery($orderId,$code,$name){
        $order = ProductOrder::where('id', $orderId)->find();
        if (!self::isDelivery($order->order_status)) {
            return false;
        }
        $order->order_status = OrderStatusEnum::SHIPMENTS;
        $order->delivery_code = $code;
        $order->delivery_name = $name;
        $order->save();

        ProductOrderProduct::where('order_id', $orderId)->update([
            'order_status' => OrderStatusEnum::SHIPMENTS,
        ]);
        //给商家发送 取消售后申请通知
        $this->noticeService->expressDeliveryNotice($orderId);
        return true;
    }


    /**
     * 删除订单
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function delOrder($orderId){
        $order = ProductOrder::where('id', $orderId)->find();
        if (!self::isDel($order->order_status)) {
            return false;
        }
        $order->status = 2;
        $order->save();
        return true;
    }


    /**
     * 超时订单处理
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function overtimeOrderHandle(){
        $orderList = ProductOrder::where('order_status', OrderStatusEnum::NOT_PAY)->select();
        if (count($orderList) > 0) {
            $time = time();
            foreach ($orderList as $order) {
                $auto_cancel = Db::table('evt_mini_user')->where('id', $order->admin_id)->value('auto_cancel');
                $auto_cancel = ($auto_cancel > 0)?  ($time - $auto_cancel*60): $time;
                if ($order->create_time <= $auto_cancel) {
                    $order->order_status = OrderStatusEnum::REPEAL;
                    $order->save();
                    ProductOrderProduct::where('order_id', $order->id)->update(['order_status' => OrderStatusEnum::REPEAL]);
                    $this->noticeService->overtimeNotice($order->id);
                }
            }
        }
    }

    /**
     * 确认（同意）退款
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function confirmRefund($orderId,$isRefundFreight){
        $order = ProductOrder::where('order_status', OrderStatusEnum::RETUREN_ING)->where('id', $orderId)->find();
        if (!$order) {
            return false;
        }
        $productList = ProductOrderProduct::where('order_id', $orderId)->select();
       
        $refundPrice = ($isRefundFreight == 1) ? $order->freight: 0;
        foreach ($productList as  $product) {
            if ($product->order_status == OrderStatusEnum::RETUREN_ING) {
                $refundProductPrice = $product->price * $product->num - $product->point_money - $product->coupon_money - $product->level_money;
                $refundPrice += $refundProductPrice;
                $product->order_status = OrderStatusEnum::RETUREN;
                $product->refund_type = RefundTypeEnum::MONEY;
                $product->refund_status = RefundStatusEnum::CONSENT;
                $product->refund_require_money = $refundProductPrice;
                $product->refund_time = time();
                $product->save();
            }
        }

        $refund_balance_money = 0;
        if ($order->payment_type == 2) { //余额支付
            $refund_balance_money = $refundPrice;
        }


        // $refundPriceTotal = $order->refund_money + $refundPrice;
        // if ($refundPriceTotal != $order->pay_money) { //确保退款不超出支付金额
        //     $refundPrice = $order->pay_money - $order->refund_money;
        // }

        $order->order_status = OrderStatusEnum::RETUREN;
        $order->refund_money = $order->refund_money + $refundPrice;
        $order->refund_balance_money = $order->refund_balance_money + $refund_balance_money;
        $order->save();


        $user = Db::table('evt_mini_member_list')->where('id', $order['user_id'])->find();

        if ($order['payment_type'] == 1) {
            $room = Db::table('evt_mini_room_list')->where('id', $order['store_id'])->find();
            $wxapp = Db::table('evt_mini_match')->where('wxapp_id', $room['admin_id'])->find();
            $wxConfig = array(
                'app_id' => $wxapp['app_id'],
                'app_key' => $wxapp['key'],
                'mchid' => $wxapp['wc_hid'],
                'app_secret' => $wxapp['api_key'],
                'apikey' => $wxapp['api_key'],
                'apiclient_url' => $wxapp['apiclient_url'],
                'apiclient_key_url' => $wxapp['apiclient_key_url']
            );
            $WxPay = new WxPay($wxConfig);
            if (!$WxPay->refund($order->out_trade_no, $order->pay_money, $refundPrice)) {
                return false;
            }
        }
        else {
            $userBa['balance'] = $user['balance'] + $refundPrice;
            if (Db::table('evt_mini_member_list')->where('id', $order['user_id'])->update($userBa)) {// 记录余额变动
                $userbalance = array(
                    'admin_id' => $user['admin_id'],
                    'price' => $refundPrice,
                    'type' => 1,
                    'status' => $order->order_sn,
                    'before_price' => $user['balance'],
                    'aater_price' => $userBa['balance'],
                    'create_time' => time(),
                    'user_id' => $user['id'],
                    'content' => "商品柜退款",
                );
                Db::table('evt_mini_admin_user_balance')->insert($userbalance);
            }

        }
        $this->noticeService->refundSuccessNotice($orderId, $refundPrice);
        return true;

    }
    
    
     /**
     * 提醒订单发货
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function remindOrder($orderId){
        $order = ProductOrder::where('id', $orderId)->find();
        if (!self::isRemind($order->status, $order->remind_time)) {
            return false;
        }
        $order->remind_time = strtotime(date('Y-m-d'));
        $order->save();

        //消息推送
        $this->noticeService->remindOrderNotice($orderId);
        return true;
    }

    /**
     * 确认拒接退款
     * @param $orderId
     * @throws DbException
     */
    public function  confirmRefuse($orderId){
        ProductOrder::where('id', $orderId)->update([
            'order_status' => OrderStatusEnum::ACCOMPLISH,
        ]);

        ProductOrderProduct::where('order_id', $orderId)->update([
            'order_status' => OrderStatusEnum::ACCOMPLISH,
            'refund_status' => RefundStatusEnum::NO_PASS_ALWAYS,
        ]);

        $this->noticeService->refundRefuseNotice($orderId);
    }


    /**
     * 是否可取消订单
     * @param $orderStatus
     * @return bool  true 是 false 否
     */
    public static function isCancel($orderStatus){
       return ($orderStatus == OrderStatusEnum::NOT_PAY)? true: false;
    }

    /**
     * 是否可确认收货
     * @param $orderStatus
     * @return bool  true 是 false 否
     */
    public static function isReceipt($orderStatus){
        return ($orderStatus == OrderStatusEnum::SHIPMENTS)? true: false;
    }
    
    /**
     * 是否可提醒发货
     * @param $orderStatus
     * @return bool  true 是 false 否
     */
    public static function isRemind($orderStatus, $remindTime){
        if ($orderStatus == OrderStatusEnum::PAY) {
            if (strtotime(date('Y-m-d')) != $remindTime) {
                return true;
            }
        }
        return false;
    }


    /**
     * 是否可立即支付
     * @param $orderStatus
     * @return bool  true 是 false 否
     */
    public static function isPay($orderStatus){
        return ($orderStatus == OrderStatusEnum::NOT_PAY)? true: false;
    }

    /**
     * 是否可申请售后
     * @param $orderStatus
     * @return bool  true 是 false 否
     * @param $orderStatus
     * @param $adminId
     * @param $orderId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function isSales($orderStatus, $adminId, $orderId){
        $info = ProductOrderProduct::where('order_id', $orderId)
            ->where('refund_status', '<', 0)
            ->find();
        if ($info) {
            return false;
        }
        $unsubscribe = Db::table('evt_mini_admin_make')->where('admin_id', $adminId)->value('is_goods_unsubscribe');
        return ($orderStatus == OrderStatusEnum::ACCOMPLISH && $unsubscribe)? true: false;
    }
    /**
     * 是否可取消申请售后
     * @param $orderStatus
     * @return bool true 是 false 否
     */
    public static function isCancelSales($orderStatus){
        return  ($orderStatus == OrderStatusEnum::RETUREN_ING) ? true: false;
    }
    /**
     * 是否可删除订单
     * @param $orderStatus
     * @return bool  true 是 false 否
     */
    public static function isDel($orderStatus){
        return ($orderStatus == OrderStatusEnum::RETUREN || $orderStatus == OrderStatusEnum::ACCOMPLISH) ? true: false;
    }


    /**
     * 是否可配送
     * @param $orderStatus
     * @return bool  true 是 false 否
     */
    public static function isDelivery($orderStatus){
        return ($orderStatus == OrderStatusEnum::PAY) ? true: false;
    }


    /**
     * 获取配送名
     * @param $deliveryType
     * @return string
     */
    public static function getDeliveryName($deliveryType){
        switch ($deliveryType) {
            case 1:
                return '到店自取';
                break;
            case 2:
                return '同城配送';
                break;
            case 3:
                return '快递配送';
                break;
        }
    }




}